/**
 * Login interceptor to validate each request send to action. This acts as filter to validate the request contains valid session object, otherwise, 
 * the request is redirected to Login page
 * @author Loganathan L
 * 
 */

package com.ims.common.action.login;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.xwork.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.StrutsStatics;
import com.ims.common.service.login.LoginService;
import com.ims.common.utils.Constants;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ValidationAware;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.PreResultListener;



public class LoginInterceptor extends AbstractInterceptor implements
		StrutsStatics, PreResultListener {

	/**
     * 
     */
	private static final Log LOG = LogFactory.getLog(LoginInterceptor.class);

	private LoginService loginService;
	private static final long serialVersionUID = 1L;
	private static final String LOGIN = "login";
	private static final String SUCCESS = "login-success";
	private String USERNAME = "username";
	private String PASSWORD = "password";
	private String username;
	private String password;
	public static final String DEFAULT_SESSION_ATTRIBUTE = "WW_TRANS_I18N_LOCALE";
	public static final String ROLE = "role";


	/**
	 * This method returns the values
	 * 
	 * @return the uSERNAME
	 */
	public String getUSERNAME() {
		return USERNAME;
	}

	/**
	 * This method sets the value
	 * 
	 * @param username
	 *            the uSERNAME to set
	 */
	public void setUSERNAME(String username) {
		USERNAME = username;
	}

	/**
	 * This method returns the values
	 * 
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * This method sets the value
	 * 
	 * @param username
	 *            the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * This method returns the values
	 * 
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * This method sets the value
	 * 
	 * @param password
	 *            the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	public LoginService getLoginService() {
		return loginService;
	}
	/**
	 * This method sets the value
	 * 
	 * @param loginService
	 *            the loginService to set
	 */
	public void setLoginService(LoginService loginService) {
		this.loginService = loginService;
	}

	/**
	 * add the value for Language listbox
	 */
	public void init() {
		LOG.info("Initializing LoginInterceptor");
	}

	/**
 * 
 */
	public void destroy() {
	}

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {

		
		 // Get the action context from the invocation so we can access the
	    // HttpServletRequest and HttpSession objects.
	    final ActionContext context = invocation.getInvocationContext ();
	    HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
	    HttpSession session =  request.getSession (true);
	    if(request.getRequestURI().equals("/IMS/logout.html")||request.getRequestURI().equals("/IMS/index.html")){
	    	session.setAttribute(Constants.USER_INFO, null);
	    	return "indexLogin";
	    }

	    // Is there a "user" object stored in the user's HttpSession?
	    Object user = session.getAttribute(Constants.USER_INFO);
	    if (user == null) {
	        // The user has not logged in yet.

	        // Is the user attempting to log in right now?
	        String loginAttempt = request.getParameter(Constants.LOGIN_ATTEMPT);
	        if (! StringUtils.isBlank(loginAttempt) ) { // The user is attempting to log in.

	            // Process the user's login attempt.
	            if (processLoginAttempt(request, session) ) {
	                // The login succeeded send them the login-success page.
	                return SUCCESS;
	            } else {
	                // The login failed. Set an error if we can on the action.
	                Object action = invocation.getAction ();
	                if (action instanceof ValidationAware) {
	                    ((ValidationAware) action).addActionError ("Username or password incorrect.");
	                }
	            }
	        }

	        // Either the login attempt failed or the user hasn't tried to login yet, 
	        // and we need to send the login form.
	        return LOGIN;
	    } else {
	    	
	        return invocation.invoke ();
	    }
	}
	
	
	/**
	 * Attempt to process the user's login attempt delegating the work to the 
	 * SecurityManager.
	 */
	public boolean processLoginAttempt (HttpServletRequest request, HttpSession session) {
	    // Get the username and password submitted by the user from the HttpRequest.
	    String username = request.getParameter (USERNAME);
	    String password = request.getParameter (PASSWORD);

	    int user=0;
		try {
			user = loginService.performLogin (username, password);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	    if (user != 0) {
	        // The user has successfully logged in. Store their user object in 
	        // their HttpSession. Then return true.
	    	if (user == 1 || user == 4 ) {
				// The user has successfully logged in. Store their user object
				// in
				// their HttpSession. Then return true.
				loginService.txUpdateUserDetails(username, 4);
				session.setAttribute(Constants.USER_INFO, user);
				session.setAttribute(Constants.LOGIN_ATTEMPT, 0);
			} else {
				increaseAttempts(session);
			}
	        
	        return true;
	    } else {
	        // The user did not successfully log in. Return false.
	        return false;
	    }
	}
	

	/**
	 * Method is used to increment the loginattempt to track no. of attempts
	 * 
	 * @param session
	 */
	private void increaseAttempts(HttpSession session) {
		Integer loginAttempts = (Integer) session.getAttribute(Constants.LOGIN_ATTEMPT);
		if (loginAttempts <= 3) {

			loginAttempts = loginAttempts + 1;
		}
		session.setAttribute(Constants.LOGIN_ATTEMPT, loginAttempts);

	}


	/*
	 * @Override public void beforeResult(ActionInvocation invocation, String
	 * arg1) { final ActionContext context = invocation.getInvocationContext();
	 * context.getValueStack().set(USERNAME, username); Object action =
	 * invocation.getAction();
	 * 
	 * }
	 */

	@Override
	public void beforeResult(ActionInvocation invocation, String resultCode) {
		
		Object action = invocation.getAction();
		if (action instanceof LoginAction) {
			return;
		}
		 
	}

}
